package com.mxf.example.service.obs;

import cn.hutool.core.util.IdUtil;
import com.alibaba.fastjson.JSONObject;
import com.mxf.example.entity.file.FileDocument;
import com.mxf.example.exception.BizException;
import com.mxf.example.utils.obs.QCloudObsTools;
import com.qingstor.sdk.exception.QSException;
import com.qingstor.sdk.service.Bucket;
import com.qingstor.sdk.service.QingStor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Date;


@Service
public class QCloudObsService {
    private final static Logger LOGGER = LoggerFactory.getLogger(QCloudObsService.class);
    @Value("${qingcloud.current_bucket}")
    private String currentBucketName;


    public QingStor.ListBucketsOutput listBuckets() {

        // 获取QingStor对象
        QingStor qingstor = QCloudObsTools.getQingStorSingleton();

        // 获取Bucket列表
        QingStor.ListBucketsOutput listOutput = null;
        try {
            listOutput = qingstor.listBuckets(null);
        } catch (QSException e) {
            throw new BizException("青云-获取Bucket列表失败");
        }
        return listOutput;

    }


    public String createBucket(String bucketName) {

        try {
            if (!StringUtils.isEmpty(bucketName)) {
                // 获取对象
                QingStor qingstor = QCloudObsTools.getQingStorSingleton();
                // 构建对象
                Bucket bucket = qingstor.getBucket(bucketName, QCloudObsTools.zone);
                Bucket.PutBucketOutput putBucketOutput = bucket.put();
                return JSONObject.toJSONString(putBucketOutput);
            }
        } catch (QSException e) {
            throw new BizException("青云-创建Bucket失败");
        }
        return null;
    }


    public Bucket.ListObjectsOutput listObjects(String bucketName) {
        try {
            if (!StringUtils.isEmpty(bucketName)) {
                // 获取QingStor对象
                QingStor qingstor = QCloudObsTools.getQingStorSingleton();
                // 获取Bucket对象
                Bucket bucket = qingstor.getBucket(bucketName, QCloudObsTools.zone);
                // 获取Object对象
                Bucket.ListObjectsOutput listOutput = bucket.listObjects(null);
                return listOutput;
            }
        } catch (QSException e) {
            throw new BizException("青云-获取Bucket-Object列表失败");
        }
        return null;
    }

    /**
     * 删除Bucket中存储的Object列表
     */
    public Bucket.DeleteObjectOutput deleteObject(String objectName) {
        try {
            if (!StringUtils.isEmpty(currentBucketName)) {
                // 获取QingStor对象
                QingStor qingstor = QCloudObsTools.getQingStorSingleton();
                // 获取Bucket对象
                Bucket bucket = qingstor.getBucket(currentBucketName, QCloudObsTools.zone);
                // 判断文件名称是否为空
                if (!StringUtils.isEmpty(objectName)) {
                    // 获取Object对象(名称是唯一的,不能重复,如果文件不存在,删除就没效果)
                    Bucket.DeleteObjectOutput deleteOutput = bucket.deleteObject(objectName);
                    return deleteOutput;
                }
            }
        } catch (QSException e) {
            throw new BizException("青云-删除Bucket中存储的Object列表失败");
        }
        return null;
    }

    /**
     * 在指定Bucket下创建一个Object对象
     */
    public FileDocument createObject(MultipartFile file) {
        try {
            if (!StringUtils.isEmpty(currentBucketName)) {

                // 获取QingStor对象
                QingStor qingstor = QCloudObsTools.getQingStorSingleton();
                // 获取Bucket对象
                Bucket bucket = qingstor.getBucket(currentBucketName, QCloudObsTools.zone);
                // 创建对象
                Bucket.PutObjectInput input = new Bucket.PutObjectInput();
                try {
                    input.setBodyInputStream(file.getInputStream());
                    input.setContentType(file.getContentType());
                    input.setContentLength(file.getSize());
                } catch (IOException e) {
                    throw new BizException("青云-获取文件长度失败");
                }
                String fileId = IdUtil.fastSimpleUUID() + file.getOriginalFilename();
                Bucket.PutObjectOutput putObjectOutput = bucket.putObject(fileId, input);
                FileDocument fileDocument = new FileDocument();
                fileDocument.setFileName(fileId);
                fileDocument.setContentType(file.getContentType());
                fileDocument.setFileSize(file.getSize());
                fileDocument.setUploadDate(new Date());
                return fileDocument;
            }
        } catch (QSException e) {
            throw new BizException("青云-上传Object失败");
        }
        return null;
    }

    /**
     * 查询青云QingStor文件,可以转换成流
     */
    public FileDocument getFileByte(String bucketName, String fileName) {
        try {
            if (!StringUtils.isEmpty(bucketName)) {
                // 获取QingStor对象
                QingStor qingstor = QCloudObsTools.getQingStorSingleton();
                Bucket bucket = qingstor.getBucket(bucketName, QCloudObsTools.zone);
                Bucket.GetObjectInput headObjectInput = new Bucket.GetObjectInput();
                Bucket.GetObjectOutput out = bucket.getObject(fileName, headObjectInput);
                if (HttpStatus.OK.value() == out.getStatueCode()) {
                    BufferedInputStream bufferedInputStream = new BufferedInputStream(out.getBodyInputStream());
                    ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
                    byte[] buffer = null;
                    int len = 0;
                    byte[] buf = new byte[2048];
                    while ((len = bufferedInputStream.read(buf)) != -1) {
                        byteArrayOutputStream.write(buf, 0, len);
                    }
                    byteArrayOutputStream.flush();
                    buffer = byteArrayOutputStream.toByteArray();
                    FileDocument fileDocument = new FileDocument();
                    fileDocument.setContent(buffer);
                    fileDocument.setContentType(out.getContentType());
                    fileDocument.setFileSize(out.getContentLength());
                    return fileDocument;
                }
            }
        } catch (QSException | IOException e) {
            throw new BizException("青云-获取Object失败");
        }
        return null;
    }
}
